<template>
  <a-modal
      :title="title"
      :width="1600"
      :open="visible"
      :maskClosable="false"
      :confirmLoading="confirmLoading"
      ok-text="确认"
      cancel-text="取消"
      @ok="handleOk"
      @cancel="handleCancel">
    <a-spin :spinning="confirmLoading">
      <a-form ref='mainForm' :model="formState" :rules="formRules">
        <!-- 主表单区域 -->
        <a-row class="form-row" :gutter="8">
          <a-col :offset="2" :span="9">
            <a-form-item name="name"
                :labelCol="labelCol"
                :wrapperCol="wrapperCol"
                label="报表名称">
              <a-input v-model:value="formState.name" placeholder="请输入报表名称"/>
            </a-form-item>
          </a-col>
          <a-col :span="7">
            <a-form-item name="code"
                :labelCol="labelCol"
                :wrapperCol="wrapperCol"
                label="编码名称">
              <a-input v-model:value="formState.code" placeholder="请输入英文编码" />
            </a-form-item>
          </a-col>
        </a-row>
        <a-row class="form-row" :gutter="8" v-show="isTable">
          <a-col :offset="2" :span="9">
            <a-form-item name="primary_key"
                :labelCol="labelCol"
                :wrapperCol="wrapperCol"
                label="业务主键">
              <a-input v-model:value="formState.primary_key" placeholder="请输入报表记录的业务主键"/>
            </a-form-item>
          </a-col>
          <a-col :span="7">
            <a-form-item name="levelField"
                :labelCol="labelCol"
                :wrapperCol="wrapperCol"
                label="分级字段">
              <a-input v-model:value="formState.levelField" placeholder="请输入分级字段名"/>
            </a-form-item>
          </a-col>
        </a-row>
        <a-row class="form-row" :gutter="8">
          <a-col :offset="2" :span="9">
            <a-form-item name="type"
                :labelCol="labelCol"
                :wrapperCol="wrapperCol"
                label="报表类型">
              <a-select v-model:value="formState.type" @change="handleChange">
                <a-select-option value="table">表格</a-select-option>
<!--                <a-select-option value="bar">柱状图</a-select-option>-->
<!--                <a-select-option value="curve">折线图</a-select-option>-->
<!--                <a-select-option value="pie">饼图</a-select-option>-->
<!--                <a-select-option value="bar-3D">3D柱状图</a-select-option>-->
<!--                <a-select-option value="curve-3D">3D折线图</a-select-option>-->
<!--                <a-select-option value="pie-3D">3D饼图</a-select-option>-->
              </a-select>
            </a-form-item>
          </a-col>
          <a-col :span="7" v-show="isTable">
            <a-form-item name="mainTable"
                :labelCol="labelCol"
                :wrapperCol="wrapperCol"
                label="主表表名">
              <a-input v-model:value="formState.mainTable" placeholder="主表表名" />
            </a-form-item>
          </a-col>
          <a-col :span="1" v-show="isTable">
            <a-popover placement="leftTop">
              <template #content>
                <p>注：当需要添加增删改功能时，必须设置！</p>
              </template>
              <template #title>
                <span>配置说明</span>
              </template>
              <QuestionCircleOutlined/>
            </a-popover>
          </a-col>
          <a-col :span="7" v-show="isAxisChart">
            <a-form-item name="nodes"
                :labelCol="labelCol"
                :wrapperCol="wrapperCol"
                label="X轴节点">
              <a-input v-model:value="formState.nodes"
                  placeholder="请输入节点列表，逗号分隔" allowClear/>
            </a-form-item>
          </a-col>
        </a-row>
        <a-row class="form-row" :gutter="8">
          <a-col :offset="2" :span="9"  v-show="isAxisChart">
            <a-form-item name="indexes"
                :labelCol="labelCol"
                :wrapperCol="wrapperCol"
                label="统计指标">
              <a-input v-model:value="formState.indexes" placeholder="index1,index2"/>
            </a-form-item>
          </a-col>
          <a-col :span="7" v-show="isAxisChart">
            <a-form-item name="dimensions"
                :labelCol="labelCol"
                :wrapperCol="wrapperCol"
                label="维度与分组">
              <a-input v-model:value="formState.dimensions" placeholder="group1,group2"/>
            </a-form-item>
          </a-col>
        </a-row>
        <a-divider />
        <a-row class="form-row" :gutter="2" >
          <a-col :span="17">
            <a-form-item name="memo"
                :labelCol="labelCol"
                :wrapperCol="wrapperCol"
                label="业务描述">
              <a-textarea placeholder="描述" :auto-size="{ minRows: 2, maxRows: 3 }" v-model:value="formState.memo"/>
            </a-form-item>
          </a-col>
          <a-col :span="7">
          </a-col>
        </a-row>
        <a-row class="form-row" :gutter="2" >
          <a-col :span="17">
            <a-form-item name="sql"
                :labelCol="labelCol"
                :wrapperCol="wrapperCol"
                label="SQL语句">
              <a-textarea placeholder="SQL or Produre"
                          :rows="10" v-model:value="formState.sql"/>
            </a-form-item>
          </a-col>
          <a-col :span="1">
            <a-popover placement="leftTop">
              <template #content>
                <p>注：#{column},${column}格式为通用字段参数占位符。</p>
                <p>#{column_begin},#{column_end}为范围字段参数</p>
                <p>#{pageSize},#{pageNo}为页面参数变量</p>
                <p>#{column},#{order}为排序参数变量</p>
                <p>示例：</p>
                <span> select field1,field2 from table where id=#{id} and username in ${username}</span>
                <p> exec sp_demo(#{id},#{name})</p>
              </template>
              <template #title>
                <span>功能说明</span>
              </template>
              <QuestionCircleOutlined />
            </a-popover>
          </a-col>
          <a-col :span="6">
            <a-button type="primary" @click="parseSql">SQL解析成配置</a-button>
          </a-col>
        </a-row>
      </a-form>
      <!-- 子表单区域 -->
      <a-tabs v-model="activeKey">
        <a-tab-pane tab="报表配置明细" key="1" :forceRender="true">
          <DraggableEditableTable
              ref="subForm"
              :loading="subTable.loading"
              :columns="subTable.columns"
              :initialData="subTable.dataSource"
              :scroll="{ x: 1300 }"
              show-sequencesequence
              showDragHandle
              deletable
              showAddRow
              @update:data="onDataUpdate"/>
        </a-tab-pane>
        <a-tab-pane tab="其它配置" key="2" :forceRender="true">
          <a-form  layout="inline">
            <!-- 主表单区域 -->
                <a-form-item>
                  <a-checkbox v-model:checked = "otherParams.printable">
                    可打印
                  </a-checkbox>
                </a-form-item>
                <a-form-item>
                  <a-checkbox v-model:checked = "otherParams.exportable">
                    可导出
                  </a-checkbox>
                </a-form-item>
                <a-form-item>
                  <a-checkbox v-model:checked = "otherParams.editable">
                    可编辑
                  </a-checkbox>
                </a-form-item>
                <a-form-item>
                  <a-checkbox v-model:checked = "otherParams.deletable">
                    可删除
                  </a-checkbox>
                </a-form-item>
                <a-form-item>
                  <a-checkbox v-model:checked = "otherParams.batch_deletable">
                    可批量删除
                  </a-checkbox>
                </a-form-item>
          </a-form>
          <a-form layout="inline">
                <a-form-item :style="{ width: '200px' }"
                    :labelCol="{ span: 16 }"
                    :wrapperCol="{span: 8}"
                    label="报表参数每行个数">
                  <a-select size="small" v-model:value = "otherParams.query_param_no_per_line">
                    <a-select-option value="2">2个</a-select-option>
                    <a-select-option value="3">3个</a-select-option>
                    <a-select-option value="4">4个</a-select-option>
                    <a-select-option value="5">5个</a-select-option>
                  </a-select>
                </a-form-item>
                <a-form-item :style="{ width: '200px' }"
                    :labelCol="{ span: 16 }"
                    :wrapperCol="{span: 8}"
                    label="表单每行项目数">
                  <a-select size="small" v-model:value = "otherParams.form_item_no_per_line">
                    <a-select-option value="1">1个</a-select-option>
                    <a-select-option value="2">2个</a-select-option>
                    <a-select-option value="3">3个</a-select-option>
                    <a-select-option value="4">4个</a-select-option>
                    <a-select-option value="5">5个</a-select-option>
                  </a-select>
                </a-form-item>
                <a-form-item :style="{ width: '240px' }"
                    :labelCol="{ span: 16 }"
                    :wrapperCol="{span: 8}"
                    label="表格字段宽度单位">
                  <a-select size="small" v-model:value = "otherParams.widthType">
                    <a-select-option value="1">百分比</a-select-option>
                    <a-select-option value="2">像素</a-select-option>
                  </a-select>
                </a-form-item>
          </a-form>
        </a-tab-pane>
      </a-tabs>
    </a-spin>
  </a-modal>
</template>

<script setup>
import { ref, reactive, onMounted } from 'vue';
import DraggableEditableTable from '@/components/YGCrm/DraggableEditableTable.vue';
import { FormTypes, VALIDATE_NO_PASSED, validateFormAndTables } from '@/utils/JEditableTableUtil';
import { saveOPage } from '@/utils/api';
import { pick } from 'lodash';
import {message} from "ant-design-vue";
import {getAction} from "@/utils/request.js";

// 定义数据变量(包括响应式)
const title = ref('操作');
const visible = ref(false);
const isTable = ref(true);
const isAxisChart = ref(false);
const isPieChart = ref(false);
const mainForm = ref(null);
const subForm = ref(null);
const confirmLoading = ref(false);
let model = {};
const labelCol = reactive({
  xs: { span: 24 },
  sm: { span: 6 }
});
const wrapperCol = reactive({
  xs: { span: 24 },
  sm: { span: 24 - 6 }
});
const activeKey = ref('1');

// 定义表单验证规则
const formRules = reactive({
  name: [
    { required: true, message: '请输入报表名称!', trigger: 'change' }
  ],
  code: [
    { required: true, pattern: /^[a-zA-Z0-9-_]+$/, message: '请输入英文编码!', trigger: 'change' }
  ],
  type: [
    { required: true, message: '请选择报表类型!', trigger: 'change' }
  ],
  nodes: [
    { required: isAxisChart, message: '请输入数据节点列表!', trigger: 'change' },
    { pattern: /^\S+(\:\s*[^,]*(,[^,]+)*)?\s*$/, message: '格式不正确', trigger: 'change' }
  ],
  indexes: [
    { required: isAxisChart, message: '请输入要统计的指标!', trigger: 'change' },
    { pattern: /^\s*[^,]*(,[^,]+)*\s*$/, message: '格式不正确', trigger: 'change' }
  ],
  dimensions: [
    { required: isAxisChart && !isPieChart, message: '请输入维度分组!', trigger: 'change' },
    { pattern: /^\s*[^,]*(,[^,]+)*\s*$/, message: '格式不正确', trigger: 'change' }
  ],
  sql: [
    { required: true, message: '请输入SQL!', trigger: 'change' }
  ]
});

const subTable = reactive({
  loading: false,
  dataSource: [],
  columns: [
    {
      title: '字段键名',
      dataIndex: 'field_name',
      width: '8%',
      align: 'center',
      type: FormTypes.input,
      defaultValue: '',
      placeholder: '请输入${title}',
      validateRules: [{ required: true, message: '${title}不能为空' }]
    },
    {
      title: '字段标签名',
      dataIndex: 'field_txt',
      width: '9%',
      align: 'center',
      type: FormTypes.input,
      defaultValue: '',
      placeholder: '请输入${title}',
      validateRules: [{ required: true, message: '${title}不能为空' }]
    },
    {
      title: '字段类型',
      dataIndex: 'field_type',
      width: '9%',
      align: 'center',
      type: FormTypes.select,
      defaultValue: 2,
      options: [ // 下拉选项
        { label: '数值类型', value: 1 },
        { label: '字符类型', value: 2 },
        { label: '日期类型', value: 3 },
        { label: '时间类型', value: 4 },
        { label: '整数类型', value: 5 },
        { label: '布尔类型', value: 6 }
      ],
      validateRules: [{ required: true, message: '${title}不能为空' }]
    },
    {
      title: '字段宽度',
      dataIndex: 'field_width',
      width: '6%',
      align: 'center',
      type: FormTypes.input,
      defaultValue: '',
      placeholder: '数字',
      validateRules: [{
        pattern: 'n,%',
        message: '${title}不在范围，请输入1-100的数字！'
      }]
    },
    {
      title: '字段对齐',
      dataIndex: 'field_align',
      width: '6%',
      align: 'center',
      type: FormTypes.select,
      defaultValue: '居中',
      options: [ // 下拉选项
        { label: '向左', value: 'left' },
        { label: '居中', value: 'center' },
        { label: '向右', value: 'right' },
      ],
    },
    {
      title: '字段子报表关联',
      dataIndex: 'field_href',
      width: '14%',
      align: 'center',
      type: FormTypes.input,
      defaultValue: '',
      placeholder: '子报表编码.字段',
      validateRules: [{
        pattern: '^[a-zA-Z0-9_]+\.[a-zA-Z0-9_]+$',
        message: '${title}格式不正确'
      }]
    },
    {
      title: '可排序',
      dataIndex: 'sortable',
      width: '3%',
      type: FormTypes.checkbox,
      defaultValue: false
    },
    {
      title: '可编辑',
      dataIndex: 'editable',
      width: '3%',
      type: FormTypes.checkbox,
      defaultValue: true
    },
    {
      title: '是否显示',
      dataIndex: 'is_show',
      width: '3%',
      type: FormTypes.checkbox,
      defaultValue: true
    },
    {
      title: '是否查询',
      dataIndex: 'is_search',
      width: '3%',
      type: FormTypes.checkbox,
      defaultValue: false
    },
    {
      title: '参数位置',
      dataIndex: 'param_order',
      width: '3%',
      type: FormTypes.input,
      defaultValue: 1,
      validateRules:[
        {pattern: 'z', message: '位置序号必须为整数！'}
      ],
    },
    {
      title: '是否必填',
      dataIndex: 'required_flag',
      width: '6%',
      align: 'center',
      type: FormTypes.select,
      defaultValue: 0,
      placeholder: '请确认${title}',
      options: [ // 下拉选项
        { label: '全否', value: '0' },
        { label: '表单', value: '1' },
        { label: '查询', value: '2' },
        { label: '全部', value: '3' }
      ]
    },
    {
      title: '查询模式',
      dataIndex: 'search_mode',
      width: '9%',
      align: 'center',
      type: FormTypes.select,
      defaultValue: 0,
      placeholder: '请选择${title}',
      options: [ // 下拉选项
        { label: '无', value: '0' },
        { label: '单条件查询', value: '1' },
        { label: '范围查询', value: '2' },
        { label: 'IN查询', value: '3' }
      ]
    },
    {
      title: '查询字典/范围/子表',
      dataIndex: 'dict_code',
      width: '22%',
      align: 'center',
      type: FormTypes.input,
      defaultValue: '',
      placeholder: '字典code/[]/表.txt->val;multi@dep',
      validateRules: [{
        pattern: '(^\s*[a-zA-Z0-9_]+\s*(;([01]))?$)|(^[_a-zA-Z0-9]+\.[_a-zA-Z0-9+]+->[_a-zA-Z0-9+]+(;([01]))?(@(.*)+)?$)|(^[[].*\](;([01]))?$)',
        message: '${title}格式不正确'
      }]
    }
  ]
});


// 定义表单数据对象
const otherParams = reactive({
  exportable: false,
  printable: false,
  deletable: false,
  batch_deletable: false,
  query_param_no_per_line: 3,
  form_item_no_per_line: 3,
  width_type: 2
});
const formState = reactive({
  name: '',
  code: '',
  primary_key: '',
  hierarchy_field: '',
  type: 'table',
  main_table: '',
  nodes: '',
  indexes: '',
  dimensions: '',
  memo: '',
  sql: ''
});


// 初始化表单
onMounted(() => {
  // 移除原有的表单初始化代码
});

// 定义方法
const emit = defineEmits(['ok', 'close'])
const parseSql = () => {
  mainForm.value
      .validate()
      .then(() => {
          let sql = formState.sql;
          sql = sql.replace(/\\n/g, " ");
          // 提取where与select中的字段
          let arrParams = sql.match(/[\#\$]{.+?}/ig);
          if (arrParams) arrParams = arrParams.map(n => n.replace(/[\#\${}]+/g, ""))
          let strFields = sql.match(/select\s+(.+?,?)\s+from.+?$/i)
          let arrFields = [];
          let arrFieldMap = {};
          if (strFields && strFields[1]) {
              strFields[1] = strFields[1].replace(/ /g, "");
              arrFields = strFields[1].split(",");
          }
          // 整合select与where中的字段
          arrFields.forEach(n => { //select
              let key = n;
              if (n.indexOf(".") !== -1) key = n.split(".")[1];
              arrFieldMap[key] = { field_name: key, is_show: true, required_flag: '0', param_order: 1, editable: true };
          });
          arrParams && arrParams.forEach(n => {//where
              let field_name = n;
              let search_mode = '1';
              if (n.indexOf('_begin') !== -1 || n.indexOf('_end') !== -1) {
                field_name = n.split('_')[0];
                search_mode = '2';
              }
              if (arrFields.includes(field_name)) { //是否是查询参数且表展现字段
                arrFieldMap[field_name].search_mode = search_mode;
                arrFieldMap[field_name].is_search = true;
              } else {
                arrFieldMap[field_name] = { field_name, is_show: false, is_search: true, search_mode: search_mode, required_flag: '0', param_order: 1 };
              }

          });
          // 原参数行保留，做为处理的基础
          let data = subTable.dataSource;
          // 增加和更新
          for (let k in arrFieldMap) {
              let index = data.findIndex(item => {
                return item['field_name'] === k;
              });
              let a = arrFieldMap[k];
              if (index < 0) {
                index = data.length;
                let newOne = Object.assign({}, a);
                data.push(newOne);
              } else {
                // 比较困难的更新用splice
                if (data[index].search_mode) a['search_mode'] = data[index].search_mode; //search_mode保持不变
                let up = Object.assign(data[index], a);
                data.splice(index, 1, up);
              }
              if (!data[index]['field_txt']) data[index]['field_txt'] = k;
          }
          subTable.dataSource = data;
          console.error(JSON.stringify(data))
      })
      .catch(error => {
          message.warning("操作失败！");
          console.log('error', error);
      });
};

// 获取所有的editableTable实例
const getAllTable = () => {
  return Promise.all([
    getRefPromise(getCurrentInstance().proxy, 'editableSubTable') // tab表引用
  ]);
};

const goAdd = () => {
  goEdit({});
};
const goEdit = (record) => {
  visible.value = true;
  activeKey.value = '1';
  Object.assign(model, record);
  console.error("model:", JSON.stringify(record));
  // 加载子表数据
  if (model.id) {
    let params = { id: model.id };
    // requestSubTableData(url.reportConfDetail, params, subTable);
  }
};
const close = () => {
  visible.value = false;
  getAllTable().then(editableTables => {
    editableTables[0].initialize();
    // editableTables[1].initialize()
  });
  emit('close');
};

const clone = (record) => {
  visible.value = true;
  activeKey.value = '1';
  Object.assign(model, record);
  // console.error(JSON.stringify(this.model))
  nextTick(() => {
    form.value.resetFields();
    form.value.setFieldsValue(pick(model, 'sql', 'memo', 'dimensions', 'indexes', 'nodes', 'type', 'hierarchy_field', 'primary_key'));
    // 时间格式化
    // this.form.setFieldsValue({ orderDate: this.model.orderDate ? moment(this.model.orderDate) : null })
    handleChange(model.type);
  });
  // 加载子表数据
  if (model.id) {
    let params = { id: model.id };
    model.id = undefined;
    requestSubTableData(url.reportConfDetail, params, subTable);
  }
};

/** 查询某个tab的数据 */
const requestSubTableData = (url, params, tab) => {
  if (tab) tab.loading = true;
  getAction(url, params).then(res => {
    if (!model.id) {
      res && res.result.map(function (r) {
        delete r['id'];
      });
    }
    res && res.result.map(function (r) {
      if (r.align) r.field_name = r.field_name + "|" + r.align.slice(0, 1);
    });
    // console.error(JSON.stringify(res))
    tab.dataSource = res.result || [];
  }).finally(() => {
    if (tab) tab.loading = false;
  });
};

const handleChange = (value = 'table') => {
  console.log(value);
  isTable.value = (value === 'table');
  if (value === 'table' || !value) {
    isAxisChart.value = false;
  } else {
    isAxisChart.value = true;
  }
  isPieChart.value = (value && value.indexOf('pie') !== -1);
};

const handleOk = () => {
  mainForm.value.validate()
      .then(() => {
        console.log('主表单验证通过');
        // console.error(JSON.stringify(data))
        let ok = subForm.value.checkIfAllPassed("子表单验证失败！")
        if (!ok) return;
        let formData = unifyIntoFormData();
        console.error(JSON.stringify(formState));
        // 发起请求
        return requestAddOrEdit(formData);
      })
      .catch(error => {
        message.warning("主表单验证失败！");
        console.log('error', error);
        return false;
      });

};

const handleCancel = () => {
  close();
};

// /** ATab 选项卡切换事件 */
// const handleChangeTabs = (key) => {
//   getRefPromise(getCurrentInstance().proxy, `editableTable${key}`).then(editableTable => {
//     editableTable.resetScrollTop();
//   });
// };

/** 整理成formData */
const unifyIntoFormData = () => {
  // 起名report是因为这种设计模式的灵感来源于report
  let reportConfig = Object.assign(model, formState, otherParams);
  return {
    ...reportConfig,
    report_config_items: subTable.dataSource,
  };
};

/** 发起新增或修改的请求 */
const requestAddOrEdit = (formData) => {
  // 参数预处理
  formData && formData.report_config_items.map(item => {
    const [field_name, align] = item['field_name']?.split("|") || [];
    item.field_name = field_name;
    if (align) {
      const lowerCaseAlign = align.toLowerCase();
      if (lowerCaseAlign === "l") {
        item.align = 'left';
      } else if (lowerCaseAlign === "c") {
        item.align = 'center';
      } else if (lowerCaseAlign === "r") {
        item.align = 'right';
      }
    }
  });
  // console.error(JSON.stringify(data))
  formData.sql = formData.sql && formData.sql.trim();
  formData.report_config_items.map(function (item, n) {
    item['order_field'] = n + 1;
  });
  // console.error(data)
  confirmLoading.value = true;
  saveOPage(formData).then((res) => {
    if (res.success) {
      message.success(res.message);
      emit('ok');
      close();
    } else {
      message.warning(res.message);
    }
  }).finally(() => {
    confirmLoading.value = false;
  });
};
const onDataUpdate = (data) => {
  console.log(data)
}

defineExpose({ goAdd, goEdit })

</script>

<style scoped>
</style>